package com.ld.shieldsb.common.web.util.params.impl;

import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.ld.shieldsb.common.core.util.DateUtil;
import com.ld.shieldsb.common.web.util.params.ParamsHandleResult;
import com.ld.shieldsb.common.web.util.params.ParamsHandler;
import com.ld.shieldsb.dao.model.QueryModel;

public class DefaultParamsHandler implements ParamsHandler {

    /**
     * 在使用正则表达式时，利用好其预编译功能，可以有效加快正则匹配速度。
     */
    private static final String CONDITION_REGEX = "\\((.+?)\\)"; // (1,2) (测试,所有) 这种
    private static Pattern CONDITION_PATTERN = Pattern.compile(CONDITION_REGEX); // (1,2) (测试,所有) 这种范围查询支持中文

    private static final String dateFormat = "yyyy-MM-dd HH:mm:ss";
    private static final String dateFormat2 = "yyyy/MM/dd HH:mm:ss";
    // 判断日期格式的正则，yyyy-MM-dd HH:mm:ss或yyyy/MM/dd HH:mm:ss
    private static final String DATEFORMAT_REGEX = "\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}|\\d{4}/\\d{2}/\\d{2} \\d{2}:\\d{2}:\\d{2}";

    private static final String shortDateFormat = "yyyy-MM-dd";
    private static final String shortDateFormat2 = "yyyy/MM/dd";
    // 判断日期格式的正则，yyyy-MM-dd或yyyy/MM/dd
    private static final String SHORT_DATEFORMAT_REGEX = "\\d{4}-\\d{2}-\\d{2}|\\d{4}/\\d{2}/\\d{2}";

    private static final String monthDateFormat = "yyyy-MM";
    private static final String monthDateFormat2 = "yyyy/MM";
    // 判断日期格式的正则，yyyy-MM或yyyy/MM
    private static final String MONTH_DATEFORMAT_REGEX = "\\d{4}-\\d{2}|\\d{4}/\\d{2}";

    @Override
    public ParamsHandleResult deal(String paramName, String paramValue, QueryModel queryModel) {
        ParamsHandleResult result = new ParamsHandleResult();
        String paramConditionDeal = "";
        String paramNameDeal = paramName;
        Object paramValueDeal = paramValue;
        paramValue = paramValue.trim();
        if (paramName.startsWith("equal_")) {// 等于
            String[] attrNames = paramName.split("equal_");
            result.setParamName(paramName);
            if (paramValue.matches(CONDITION_REGEX)) { // in 条件
                Matcher m = CONDITION_PATTERN.matcher(paramValue);
                if (m.find()) {
                    String valuesStr = m.group(1);
                    String[] valuesStrArrs = valuesStr.split(","); // 以英文,分隔
                    if (valuesStrArrs.length > 0) {
                        paramConditionDeal = attrNames[0];
                        paramNameDeal = attrNames[1];
                        paramValueDeal = valuesStrArrs;
                        queryModel.addInSet(paramNameDeal, valuesStrArrs);
                    }
                }
            } else {
                paramConditionDeal = "equal_";
                paramNameDeal = attrNames[1];
                queryModel.addEq(paramNameDeal, paramValueDeal);
            }
        } else if (paramName.startsWith("notEqual_")) { // 不等于
            String[] attrNames = paramName.split("notEqual_");
            paramConditionDeal = "notEqual_";
            paramNameDeal = attrNames[1];
            queryModel.addUnEq(paramNameDeal, paramValue);
        }
        // ============================== 模糊查询 begin ====================================
        else if (paramName.startsWith("like_")) {// 模糊查询
            String[] attrNames = paramName.split("like_");
            paramConditionDeal = "like_";
            paramNameDeal = attrNames[1];
            queryModel.addLike(paramNameDeal, paramValue);
        } else if (paramName.startsWith("like1_")) {// 模糊查询
            String[] attrNames = paramName.split("like1_");
            paramConditionDeal = "like1_";
            paramNameDeal = attrNames[1];
            queryModel.addRightLike(paramNameDeal, paramValueDeal.toString()); // "%" + paramValue
        } else if (paramName.startsWith("like2_")) {// 模糊查询
            String[] attrNames = paramName.split("like2_");
            paramConditionDeal = "like2_";
            paramNameDeal = attrNames[1];
            queryModel.addLeftLike(paramNameDeal, paramValueDeal.toString()); // paramValue + "%"
        } else if (paramName.startsWith("like3_")) {// 模糊查询,与fuzzy_一致
            String[] attrNames = paramName.split("like3_");
            paramConditionDeal = "like3_";
            paramNameDeal = attrNames[1];
            queryModel.addLike(paramNameDeal, paramValueDeal.toString());
        } else if (paramName.startsWith("like4_")) {// 模糊查询 带，号
            String[] attrNames = paramName.split("like4_");
            paramConditionDeal = "like4_";
            paramNameDeal = attrNames[1];
            QueryModel likeQueryM1 = new QueryModel();
            likeQueryM1.addLeftLike(paramNameDeal, paramValueDeal + ","); // paramValue + ",%"
            QueryModel likeQueryM2 = new QueryModel();
            likeQueryM2.addRightLike(paramNameDeal, "," + paramValueDeal); // "%," + paramValue
            QueryModel likeQueryM3 = new QueryModel();
            likeQueryM3.addLike(paramNameDeal, "," + paramValueDeal + ","); // "%," + paramValue + ",%"
            QueryModel likeQueryM4 = new QueryModel();
            likeQueryM4.addEq(paramNameDeal, paramValueDeal); // "=", paramValue
            queryModel.addOrMultiCondition(likeQueryM1, likeQueryM2, likeQueryM3, likeQueryM4);
        }
        // ============================== 模糊查询 end ====================================
        // ============================== 日期相关 begin ====================================
        else if (paramName.startsWith("date_")) {// 日期查询
            // 做其他日期格式的兼容处理
            if (paramValue.matches(SHORT_DATEFORMAT_REGEX)) { // 日期
                return dealDate(paramNameDeal, paramValue, queryModel, "date_s", "date_e");
            } else if (paramValue.matches(DATEFORMAT_REGEX)) { // 时间
                return dealDateTime(paramNameDeal, paramValue, queryModel, "date_s", "date_e");
            } else if (paramValue.matches(MONTH_DATEFORMAT_REGEX)) { // 年月
                return dealDateMonth(paramNameDeal, paramValue, queryModel, "date_s", "date_e");
            } else if (paramValue.length() == 4) { // 年
                return dealDateYear(paramNameDeal, paramValue, queryModel, "date_s", "date_e");
            } else {
                paramConditionDeal = "date_";
                queryModel.addEq(paramNameDeal, paramValueDeal);
            }
        } else if (paramName.startsWith("time_")) {// 日期时间查询
            return dealDateTime(paramNameDeal, paramValue, queryModel, "time_s", "time_e");
        } else if (paramName.startsWith("month_")) {// 月份查询
            return dealDateMonth(paramNameDeal, paramValue, queryModel, "month_s", "month_e");
        } else if (paramName.startsWith("year_")) {// 年查询
            return dealDateYear(paramNameDeal, paramValue, queryModel, "year_s", "year_e");
        }
        // ============================== 日期相关 end ====================================
        else if (paramName.startsWith("range_")) {// 范围查询
            if (paramName.startsWith("range_gt")) {// 大于值 gt
                String[] attrNames = paramName.split("range_gt");
                paramConditionDeal = "range_gt";
                paramNameDeal = attrNames[1];
                queryModel.addGt(paramNameDeal, paramValueDeal);
            }
            if (paramName.startsWith("range_lt")) {// 小于值 lt
                String[] attrNames = paramName.split("range_lt");
                paramConditionDeal = "range_lt";
                paramNameDeal = attrNames[1];
                queryModel.addLt(paramNameDeal, paramValueDeal);
            }
            if (paramName.startsWith("range_ge")) {// 大于值 gteq
                String[] attrNames = paramName.split("range_ge");
                paramConditionDeal = "range_ge";
                paramNameDeal = attrNames[1];
                queryModel.addGe(paramNameDeal, paramValueDeal);
            }
            if (paramName.startsWith("range_le")) {// 小于值 lteq
                String[] attrNames = paramName.split("range_le");
                paramConditionDeal = "range_le";
                paramNameDeal = attrNames[1];
                queryModel.addLe(paramNameDeal, paramValueDeal);
            }
        } else if (paramName.startsWith("area_")) { // 区域查询
            String[] attrNames = paramName.split("area_");
            paramConditionDeal = "area_";
            paramNameDeal = attrNames[1];
            queryModel.addCondition(paramNameDeal + " IN (SELECT areacode FROM sys_area WHERE areacode='" + paramValueDeal
                    + "' OR parentCodes LIKE '%" + paramValueDeal + "%')");
        } else {
            queryModel.addEq(paramName, paramValue);
        }
        result.setParamCondition(paramConditionDeal);
        result.setParamName(paramNameDeal);
        result.setParamValue(paramValueDeal);
        result.setQueryModel(queryModel);
        return result;
    };

    public ParamsHandleResult deal(String paramName, String paramValue) {
        return deal(paramName, paramValue, new QueryModel());
    };

    /**
     * 日期时间参数处理，年月日时分秒，如2019-09-04 08:46:16
     * 
     * @Title dealDateTime
     * @author 吕凯
     * @date 2019年9月4日 上午8:45:56
     * @param paramName
     * @param paramValue
     * @param queryModel
     * @param startPrefix
     * @param endPrefix
     * @return ParamsHandleResult
     */
    public ParamsHandleResult dealDateTime(String paramName, String paramValue, QueryModel queryModel, String startPrefix,
            String endPrefix) {
        ParamsHandleResult result = new ParamsHandleResult();
        String paramCondition = null;
        String paramNameDeal = null;
        Date paramValueDeal = null;
        if (paramValue.contains("-")) {
            paramValueDeal = DateUtil.str2Date(paramValue, dateFormat);
        } else if (paramValue.contains("/")) {
            paramValueDeal = DateUtil.str2Date(paramValue, dateFormat2);
        }
        if (paramName.startsWith(startPrefix)) {// 日期大于
            String[] attrNames = paramName.split(startPrefix);
            paramCondition = startPrefix;
            paramNameDeal = attrNames[1];
            // paramValueDeal = DateUtil.str2Date(paramValue);
            queryModel.addGe(paramNameDeal, paramValueDeal);
        }
        if (paramName.startsWith(endPrefix)) {// 日期小于
            String[] attrNames = paramName.split(endPrefix);
            paramCondition = startPrefix;
            paramNameDeal = attrNames[1];
            queryModel.addLe(paramNameDeal, paramValueDeal); // 不会包含多加的1天
        }
        result.setParamCondition(paramCondition);
        result.setParamName(paramNameDeal);
        result.setParamValue(paramValueDeal);
        result.setQueryModel(queryModel);
        return result;
    }

    /**
     * 
     * 日期格式参数处理，年月日，如2019-09-04
     * 
     * @Title dealDate
     * @author 吕凯
     * @date 2019年9月4日 上午8:46:31
     * @param paramName
     * @param paramValue
     * @param queryModel
     * @param startPrefix
     * @param endPrefix
     * @return ParamsHandleResult
     */
    public ParamsHandleResult dealDate(String paramName, String paramValue, QueryModel queryModel, String startPrefix, String endPrefix) {
        ParamsHandleResult result = new ParamsHandleResult();
        String paramCondition = null;
        String paramNameDeal = null;
        Date paramValueDeal = null;
        Date valDate = null;
        if (paramValue.contains("-")) {
            valDate = DateUtil.str2Date(paramValue, shortDateFormat);
        } else if (paramValue.contains("/")) {
            valDate = DateUtil.str2Date(paramValue, shortDateFormat2);
        }
        if (paramName.startsWith(startPrefix)) {// 日期大于
            String[] attrNames = paramName.split(startPrefix);
            paramCondition = startPrefix;
            paramNameDeal = attrNames[1];
            paramValueDeal = valDate;
            // paramValueDeal = DateUtil.str2Date(paramValue);
            queryModel.addGe(paramNameDeal, paramValueDeal);
        }
        if (paramName.startsWith(endPrefix)) {// 日期小于

            String[] attrNames = paramName.split(endPrefix);
            // Date endDate = DateUtil.addDate(DateUtil.str2Date(paramValue), 1, Calendar.DAY_OF_MONTH); // 加1天 ，减去1秒
            Date endDate = DateUtil.addDate(DateUtil.addDate(valDate, 1, Calendar.DAY_OF_MONTH), -1, Calendar.SECOND);
            // // 加1天
            paramCondition = endPrefix;
            paramNameDeal = attrNames[1];
            paramValueDeal = endDate;
            queryModel.addLe(paramNameDeal, paramValueDeal); // 不会包含多加的1天
        }
        result.setParamCondition(paramCondition);
        result.setParamName(paramNameDeal);
        result.setParamValue(paramValueDeal);
        result.setQueryModel(queryModel);
        return result;
    }

    /**
     * 年月参数处理，年月，如2019-09，若为开始时间则处理为2019-09-01（包含），结束时间处理为2019-09-30（包含）
     * 
     * @Title dealDateMonth
     * @author 吕凯
     * @date 2019年9月4日 上午8:47:02
     * @param paramName
     * @param paramValue
     * @param queryModel
     * @param startPrefix
     * @param endPrefix
     * @return ParamsHandleResult
     */
    public ParamsHandleResult dealDateMonth(String paramName, String paramValue, QueryModel queryModel, String startPrefix,
            String endPrefix) {
        ParamsHandleResult result = new ParamsHandleResult();
        String paramCondition = null;
        String paramNameDeal = null;
        Date paramValueDeal = null;
        if (paramName.startsWith(startPrefix)) {// 日期大于
            String[] attrNames = paramName.split(startPrefix);
            paramCondition = startPrefix;
            paramNameDeal = attrNames[1];
            if (paramValue.contains("-")) {
                paramValueDeal = DateUtil.str2Date(paramValue + "-01", shortDateFormat);
            } else if (paramValue.contains("/")) {
                paramValueDeal = DateUtil.str2Date(paramValue + "/01", shortDateFormat2);
            }
            queryModel.addGe(paramNameDeal, paramValueDeal);
        }
        if (paramName.startsWith(endPrefix)) {// 日期小于
            String[] attrNames = paramName.split(endPrefix);
            paramCondition = endPrefix;
            paramNameDeal = attrNames[1];
            Date valDate = null;
            if (paramValue.contains("-")) {
                valDate = DateUtil.getMaxDateMonth(paramValue, monthDateFormat);
            } else if (paramValue.contains("/")) {
                valDate = DateUtil.getMaxDateMonth(paramValue, monthDateFormat2);
            }
            paramValueDeal = valDate;
            queryModel.addLe(paramNameDeal, paramValueDeal); // 不会包含多加的1天
        }
        result.setParamCondition(paramCondition);
        result.setParamName(paramNameDeal);
        result.setParamValue(paramValueDeal);
        result.setQueryModel(queryModel);
        return result;
    }

    /**
     * 年参数处理，如2019，开始时间处理为2019-01-01（包含），结束时间2020-01-01（不包含）
     * 
     * @Title dealDateYear
     * @author 吕凯
     * @date 2019年9月4日 上午8:47:27
     * @param paramName
     * @param paramValue
     * @param queryModel
     * @param startPrefix
     * @param endPrefix
     * @return ParamsHandleResult
     */
    public ParamsHandleResult dealDateYear(String paramName, String paramValue, QueryModel queryModel, String startPrefix,
            String endPrefix) {
        ParamsHandleResult result = new ParamsHandleResult();
        String paramCondition = null;
        String paramNameDeal = null;
        Date paramValueDeal = null;
        if (paramName.startsWith(startPrefix)) {// 日期大于
            String[] attrNames = paramName.split(startPrefix);
            paramCondition = startPrefix;
            paramNameDeal = attrNames[1];
            paramValueDeal = DateUtil.str2Date(paramValue + "-01-01", shortDateFormat);
            queryModel.addGe(paramNameDeal, paramValueDeal);
        }
        if (paramName.startsWith(endPrefix)) {// 日期小于
            String[] attrNames = paramName.split(endPrefix);
            paramCondition = endPrefix;
            paramNameDeal = attrNames[1];
            Date endDate = DateUtil.addDate(DateUtil.str2Date(paramValue + "-12-31", shortDateFormat), 1, Calendar.DAY_OF_MONTH); // 加1天
            paramValueDeal = endDate;
            queryModel.addLe(paramNameDeal, paramValueDeal); // 不会包含多加的1天
        }
        result.setParamCondition(paramCondition);
        result.setParamName(paramNameDeal);
        result.setParamValue(paramValueDeal);
        result.setQueryModel(queryModel);
        return result;
    }
}
